﻿using CRL.Core;
using CRL.Data;
using CRL.Data.DBAccess;
using CRL.Elasticsearch;
using Nest;
using System;
using System.Collections.Generic;
using System.Linq;

namespace esTest
{
    class Program
    {
        static ElasticClient _esClient;
        static void Main(string[] args)
        {
            var builder = DBConfigRegister.GetInstance();
            builder.UseElasticsearch();
            var connectionString = "http://127.0.0.1:9200/testindex";
            var indexName = "testindex";
            //定义连接设置
            Func<ConnectionSettings, ConnectionSettings> func = (setting) =>
            {
                setting.DefaultMappingFor<GoodsInfo>(m => m.IndexName(indexName));
                setting.DefaultMappingFor<GoodsInfoChild>(m => m.IndexName(indexName));
                return setting;
            };
            builder.RegisterDBAccessBuild(dbLocation =>
            {
                var dBAccessBuild = new DBAccessBuild(DBType.ES, connectionString);

                dBAccessBuild.Data = func;
                return dBAccessBuild;
            });
            var setting = new ConnectionSettings(new Uri(connectionString)).DefaultFieldNameInferrer((name) => name).DefaultIndex(indexName);
            func(setting);
            _esClient = new ElasticClient(setting);
            ConsoleTest.DoCommand(typeof(Program));
        }
        public static void CreateMapping()
        {
            var names = @"八宝五胆药墨
川芎
石菖蒲
超声经颅多普勒血流分析仪
负压引流装置 塑料
生脉注射液
复方丹参滴丸
益母草膏
苏迪
利肺胶囊";
            names = @"
注射用阿莫西林钠克拉维酸钾
阿莫西林颗粒
注射用阿莫西林钠舒巴坦钠
阿莫西林克拉维酸钾干混悬剂
阿莫西林胶囊
阿莫西林分散片
阿莫西林克拉维酸钾片";
            var service = new GoodsService();
            service.DropTable();
            service.CreateEsIndex();
            var query = service.GetLambdaQuery();
            var list = new List<GoodsInfo>();
            var arry = names.Split('\r').ToList();
            //int i = 0;
            for (int i = 0; i <= 10; i++)
            {
                var name = $"goods{i}";
                if (i < arry.Count)
                {
                    name = arry[i];
                }
                if (string.IsNullOrEmpty(name))
                {
                    continue;
                }
                //i += 1;
                var words = query.Analyze(name, "ik_max_word").Select(b => b.Token);
                var rand = new System.Random();
                list.Add(new GoodsInfo
                {
                    Id = i.ToString(),
                    DataType = "Goods",
                    Name = name,
                    Name2 = string.Join(" ", words),
                    Number = i,
                    Enable = true,
                    remark = $"201010_451100",
                    Sort = rand.Next(1, 100)
                }); ;//010102
            }
            service.BatchInsert(list);
            var service2 = new GoodsInfoChildService();
            var childs = new List<GoodsInfoChild>();
            childs.Add(new GoodsInfoChild("1", "100", "Group") { GroupCode = "001" });
            childs.Add(new GoodsInfoChild("2", "200", "Group") { GroupCode = "002" });
            childs.Add(new GoodsInfoChild("3", "300", "Area") { GroupCode = "003" });
            childs.Add(new GoodsInfoChild("4", "400", "Area") { GroupCode = "004" });
            service2.BatchInsert(childs);
            service2.Add(new GoodsInfoChild("5", "500", "Area") { GroupCode = "005" });
        }
        public static void testExtension()
        {
            var db = _esClient.GetDBExtend();
            db.InsertFromObj(new GoodsInfoChild("5", "500", "Area") { GroupCode = "005" });
            //使用扩展
            var query = _esClient.GetLambdaQuery<GoodsInfo>();
            var args = new List<int> { 1, 2, 3 };
            //query.Select(b => b.Name2);
            var list = query.Where(b => b.Enable == true).ToList();
            foreach (var item in list)
            {
                Console.WriteLine(item.Name);
            }
        }
        public static void testDelete()
        {
            var service = new GoodsService();
            var n = service.Delete(b => b.Name.Contains("goods"));
        }
        public static void testQuery()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            var args = new List<int> { 1, 2, 3 };
            //query.Select(b => b.Name2);
            var list = query.Where(b => b.Enable == true).ToList();
            foreach (var item in list)
            {
                Console.WriteLine(item.Name);
            }
            query.PrintQuery();
        }
        public static void testQueryAnd()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            query.Where(b => b.DataType == "Goods" && b.Id != "2");
            //query.Where(b => b.Name.WithTermsQuery(new List<string> { "sss"}));
            //query.PrintQuery();
            var list = query.ToList();
            query.PrintQuery();
            Console.WriteLine($"count should 9 {list.Count == 9}");
            query.PrintQuery();
        }
        public static void testQueryAnd2()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            query.Where(b => b.DataType == "Goods" && b.Id != "2" && b.Id != "3");
            query.PrintQuery();
            var list = query.ToList();
            Console.WriteLine($"count should 8 {list.Count == 8}");
            query.PrintQuery();
        }
        public static void testQueryAnd3()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            query.Where(b => b.DataType == "Goods");
            query.Where(b => b.Id == "2");
            query.Where(b => b.Name != "goods");
            query.PrintQuery();
            var list = query.ToList();
            Console.WriteLine($"count should 1 {list.Count == 1}");
            query.PrintQuery();
        }
        public static void testQueryOr()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            query.Where(b => b.DataType == "Goods");
            query.Where(b => b.Id == "2" || b.Id == "3");
            query.PrintQuery();
            var list = query.ToList();
            Console.WriteLine($"count should 2 {list.Count == 2}");
            query.PrintQuery();
        }
        public static void testAggregationCount()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            query.Where(b => b.DataType == "Goods");
            query.GroupBy(b => new { b.DataType, b.Name });
            var list = query.ToAggregationCount();
            Console.WriteLine($"count should 2 {list.Count == 2}");
            query.PrintQuery();
        }
        public static void testAggregationCount2()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            query.Where(b => b.DataType == "Goods");
            query.GroupBy(b => new { b.DataType });
            var list = query.ToList();
            var aggregation = query.GetAggregationCount();
            Console.WriteLine($"count should 1 {aggregation.Count == 1}");
            query.PrintQuery();
        }

        public static void testMethod()
        {
            var service = new GoodsService();
            var ids = new List<Id>();
            ids.Add("1");
            var list = service.QueryList(b => b.DataType == "Goods" && b.WithIdsQuery(ids));
            Console.WriteLine($"count should 1 {list.Count == 1}");
        }
        public static void testMethod2()
        {
            var service = new GoodsService();
            var list = service.QueryList(b => b.Name.WithMatchQuery("goods1", Operator.And));
            Console.WriteLine($"count should 1 {list.Count == 1}");
        }
        public static void testMethodAll()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            var ids = new List<Id>();
            ids.Add("1");
            query.Where(b => b.WithIdsQuery(ids));
            query.Where(b => b.Name.WithWildcardQuery("goods*"));
            //query.Where(b => b.Name.WithTermQuery("goods"));
            //query.Where(b => b.Name.WithMatchQuery("goods", Operator.And));
            //query.Where(b => b.Name.WithMatchPhraseQuery("goods"));
            query.Where(b => b.WithMultiMatchQuery(new string[] { "Name", "DataType" }, "goods", Operator.And, TextQueryType.BestFields));
            //query.Where(b => b.WithQueryBase(new WildcardQuery
            //{
            //    Field = "Name",
            //    Value = "goods"
            //}));
            query.PrintQuery();
        }
        public static void testChildQuery()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery().Where(b => b.DataType == "Goods");
            var queryChild = query.CreateQuery<GoodsInfoChild>();
            queryChild.Where(b => b.GroupCode == "001" && b.DataType == "Group");
            query.HasChild(queryChild);
            var list = query.ToList();
            Console.WriteLine($"count should 1 {list.Count == 1}");
            query.PrintQuery();
        }
        public static void testChildQueryOr()
        {
            //子查询或
            var service = new GoodsService();
            var query = service.GetLambdaQuery().Where(b => b.DataType == "Goods");

            var queryChild = query.CreateQuery<GoodsInfoChild>();
            //var service2 = new GoodsInfoChildService();
            //var query2 = service2.GetLambdaQuery().Where(b => (b.GroupCode == "001" && b.DataType == "Group") || b.GroupCode == "003" && b.DataType == "Area");
            //var list2 = query2.ToList();

            queryChild.Where(b => (b.GroupCode == "001" && b.DataType == "Group") || (b.GroupCode == "003" && b.DataType == "Area"));
            query.HasChild(queryChild);
            var list = query.ToList();
            query.PrintQuery();
            Console.WriteLine($"count should 2 {list.Count == 2}");
        }
        public static void testChildQueryOr2()
        {
            //子查询和主查询或
            var service = new GoodsService();
            var query = service.GetLambdaQuery().Where(b => b.DataType == "Goods");
            var areaGoodsIds = new List<string>() { "2" };
            var queryChild = query.CreateQuery<GoodsInfoChild>();
            queryChild.Where(b => b.GroupCode == "001" && b.DataType == "Group" && !areaGoodsIds.Contains(b.Id));
            query.HasChild(queryChild, b => areaGoodsIds.Contains(b.Id));
            //query.Or(b => areaGoodsIds.Contains(b.Id));
            var list = query.ToList();
            query.PrintQuery();
            Console.WriteLine($"count {list.Count} should 2 {list.Count == 2}");
        }

        public static void testCountChild()
        {
            var service2 = new GoodsInfoChildService();
            var count = service2.Count(b => b.DataType == "Group");
            Console.WriteLine($"count  {count}");
        }
        public static void testBoolQuery()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            var bq = new BoolQuery()
            {
                Filter = new List<QueryContainer> { EsQueryCreater.CreateMatchPhraseQuery("DataType", "Goods") },
                Should = new List<QueryContainer> { EsQueryCreater.CreateMatchPhraseQuery("Name", "123") }
            };
            query.Where(b => b.WithQueryBase(bq));
            query.PrintQuery();
            var list = query.ToList();
        }
        public static void testBoolQuery2()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            var bqCreater = new BoolQueryCreater<GoodsInfo>(query);
            bqCreater.SetFilter(x => x.Number == 4);
            bqCreater.SetShould(x => x.Number < 3);
            //bqCreater.SetMust(x => x.Name == "123");
            //bqCreater.SetMustNot(b => b.Id == "2" && b.DataType == "Goods" && b.Number == 2);
            //query.Where(b => b.WithQueryBase(creater));
            query.WithBoolQuery(bqCreater);
            query.PrintQuery();
            var list = query.ToList();
        }

        public static void testGroup()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            query.GroupBy(b => b.Name);
            query.GroupBy(b => b.remark);
            var result = query.ToList();
            var groupDic = query.GetAggregationCount();
            query.PrintQuery();
        }
        static void queryKeyword(string keyword)
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            query.Where(b => b.Number < 99);
            query.Where(b => b.Name.WithMatchQuery(keyword, Operator.And));

            //query.OrderBy(b => b.Number);
            query.OrderBy("_score desc");
            //query.PrintQuery();
            var list = query.ToList();
            foreach (var item in list)
            {
                Console.WriteLine(item.Name.Replace(keyword, $"[{keyword}]"));
            }
            Console.WriteLine($"count {list.Count}");
            query.PrintQuery();
        }
        public static void testAnalyze()
        {
            //queryKeyword("五胆药墨");
            //queryKeyword("药墨");
            //queryKeyword("八宝");
            //queryKeyword("胆药");
            //queryKeyword("八宝五胆药墨");
            //queryKeyword("八宝药墨");
            //queryKeyword("八宝药");
            //queryKeyword("复方滴丸");
            queryKeyword("阿莫 克拉维 酸钾片");
            //queryKeyword("阿莫西林胶囊");
            //queryKeyword("阿莫西林颗粒");
        }
        public static void testHighlight()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            var keyWord = "阿莫";
            query.Where(b => b.Name.Contains(keyWord));
            query.Highlight(b => b.Name);
            var list = query.ToList();
            foreach (var item in list)
            {
                Console.WriteLine(item.Name);
            }
            Console.WriteLine($"count {list.Count}");
            query.PrintQuery();
        }
        public static void testContains()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery();
            var types = new List<string> { "Goods" };
            query.Where(b => types.Contains(b.DataType)); //字段为型必须设置为Keyword
            var list = query.ToList();
            foreach (var item in list)
            {
                Console.WriteLine($"{item.DataType} {item.Name}");
            }
            query.PrintQuery();
        }
        public static void testSort()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery().Where(b => b.DataType == "Goods");
            query.OrderBy(b => b.Sort, true);
            query.OrderBy(b => b.Number, true);
            var list = query.ToList();
            //var sql = query.PrintQuery();
            foreach (var item in list)
            {
                Console.WriteLine($"{item.Name} Sort:{item.Sort} Number:{item.Number}");
            }
            query.PrintQuery();
        }
        public static void testObj()
        {
            var service = new GoodsService();
            var query = service.GetLambdaQuery().Where(b => b.DataType == "Goods");
            var view = query.Select(b => new { b.Name, b.Number });
            var result = query.ToDynamic();
            var result2 = view.ToList();
        }
    }
}
